package cmd

import (
	"context"
	"fmt"
	"io"
	"os"
	"path"

	reqV3 "github.com/imroc/req/v3"
)

type UploadReq struct {
	Path   string    // cos save path without filename
	Name   string    // cos save name
	Reader io.Reader // cos save file
}

type UploadRes struct {
	Files []string `json:"uploaded_files"`
	Err   string   `json:"err_info"`
}

func (tr *TaskRunner) uploadToDpOperWeb(ctx context.Context, url string, reqs []UploadReq, opts ...UploadOption) (err error) {
	opt := tr.withOptions(opts...)
	res := &UploadRes{}
	client := reqV3.C().SetUserAgent(opt.UserAgent).SetTimeout(opt.Timeout)
	request := client.EnableDumpAllWithoutRequestBody().R().
		SetContext(ctx).
		// SetFormData(map[string]string{
		// 	"bucket_prefix": s.bucketPrefix,
		// }).
		// SetFileBytes("crawler-result.json", "products.json", []byte("test content")).
		SetResult(res)
	for _, req := range reqs {
		request.SetFileReader(req.Path, req.Name, req.Reader)
	}
	resp, err := request.Post(url)
	if err != nil {
		return
	}
	if resp.IsError() {
		// s.slog.Error(fmt.Errorf("parse err"))
		err = fmt.Errorf("parse err on Upload:%+v", resp.Error())
		return
	}
	if resp.IsSuccess() {
		if res.Err != "" {
			err = fmt.Errorf("upload Err:%s", res.Err)
			return
		}
	}
	slog.Debugf("files to upload:%s", res.Files)
	return
}

func (tr *TaskRunner) uploadFilesToDpOperWeb(ctx context.Context, url string, files []string, opts ...UploadOption) (err error) {
	reqs := []UploadReq{}
	for _, file := range files {
		f, err := os.Open(file)
		if err != nil {
			return err
		}
		defer f.Close()

		reqs = append(reqs, UploadReq{
			Name:   path.Base(file),
			Path:   file,
			Reader: f,
		})
	}

	return tr.uploadToDpOperWeb(ctx, url, reqs, opts...)
}

func (tr *TaskRunner) UploadSearchWithShopesAndReviews(host string, files []string) {
	ctx := context.Background()
	url := fmt.Sprintf("%s/search/upload", host)
	err := tr.uploadFilesToDpOperWeb(ctx, url, files, UserAgent("dp"))
	if err != nil {
		fmt.Printf("upload search err:%+v\n", err)
		return
	}
	fmt.Println("1、search file uploaded")

	var shopFiles []string
	var reviewFiles []string
	for _, file := range files {
		v, err := ReadJson[SearchResultInfo](file)
		if err != nil {
			fmt.Printf("read search files err:%+v\n", err)
			return
		}
		for _, shopItem := range v.Shopes {
			shopFile := fmt.Sprintf("%s/shop/%s.json", crawledDir, shopItem.ID)
			reviewFile := fmt.Sprintf("%s/review/%s.json", crawledDir, shopItem.ID)
			if tr.CheckFileExist(shopFile) {
				shopFiles = append(shopFiles, shopFile)
			}
			if tr.CheckFileExist(reviewFile) {
				reviewFiles = append(reviewFiles, reviewFile)
			}
		}
	}
	if len(shopFiles) > 0 {
		url = fmt.Sprintf("%s/shop/upload", host)
		err = tr.uploadFilesToDpOperWeb(ctx, url, shopFiles, UserAgent("dp"))
		if err != nil {
			fmt.Printf("upload shop err:%+v\n", err)
			return
		}
		fmt.Println("2、shop files uploaded")
	} else {
		fmt.Println("2、no shop files uploaded")
	}

	if len(reviewFiles) > 0 {
		url = fmt.Sprintf("%s/review/upload", host)
		err = tr.uploadFilesToDpOperWeb(ctx, url, shopFiles, UserAgent("dp"))
		if err != nil {
			fmt.Printf("upload review err:%+v\n", err)
			return
		}
		fmt.Println("3、review files uploaded")
	} else {
		fmt.Println("3、no review files uploaded")
	}

}

func (tr *TaskRunner) UploadShops(host string, files []string) {
	ctx := context.Background()
	url := fmt.Sprintf("%s/shop/upload", host)
	err := tr.uploadFilesToDpOperWeb(ctx, url, files, UserAgent("dp"))
	if err != nil {
		fmt.Printf("upload shop err:%+v\n", err)
	}
}

func (tr *TaskRunner) UploadShopReviews(shopID, host string, files []string) {
	ctx := context.Background()
	url := fmt.Sprintf("%s/review/%s/upload", host, shopID)
	err := tr.uploadFilesToDpOperWeb(ctx, url, files, UserAgent("dp"))
	if err != nil {
		fmt.Printf("upload review err:%s\n", err)
	}
}
